//console.time( 'Service_start' );

//{{{require modules
var libHttp	= require( 'http' );
var libUrl	= require( 'url' );
var libFs	= require( "fs" );
var libPath	= require( "path" );
var libQs	= require( "querystring" );
var libCluster = require('cluster');
var libOs = require('os');
//}}}

//{{{host setting
var wwwRoot		= "D:/Projects/ta/";
//var wwwRoot		= "D:/E/Projects/web/";
/*
if(process.argv[2]){
	wwwRoot = libFs.realpathSync(process.argv[2]);
	console.log( wwwRoot );
}
*/
var host		= "localhost";
var port		= "83";
var index		= "";
var service_log	= "D:/node.a.log";
var visit_log	= "D:/node.b.log";
//}}}

//{{{wlog
var log = function(data){
	libFs.appendFileSync(visit_log, data + "\n");
};
//console.log = log;
//}}}

//{{{deal setting
var hostPort = host + ':' + port;
wwwRoot = wwwRoot.replace('\\', '/').replace(/\/$/, '');
//console.log('--------------------------------------');
//console.log('Platform: ' + process.platform);
//console.log('Version: ' + process.version);
//console.log('Title: ' + process.title);
//console.log('Node at: ' + process.execPath);
//console.log("Server script at: " + __dirname);
//console.log("Server script name is: " + __filename);
process.chdir(wwwRoot);
//console.log('Currend Working Directory: ' + process.cwd());
//console.log('--------------------------------------');
//}}}

//fn getContentType{{{
var contentType = {
	'txt'		: 'text/plain',
	'html'		: 'text/html; charset=utf-8',
	'htm'		: 'text/html; charset=utf-8',
	'rar'		: 'application/x-rar-compressed',
	'zip'		: 'application/zip',
	'json'		: 'application/json',
	'js'		: 'application/javascript',
	'swf'		: 'application/x-shockwave-flash',
	'css'		: 'text/css',
	'gif'		: 'image/gif',
	'jpg'		: 'image/jpeg',
	'png'		: 'image/png',
	'ico'		: 'image/icon',
	'download'	: 'application/force-download',
	'stream'	: 'application/force-download'
};
var getContentType = function( filePath ){
	var type	= "";
	var ext		= libPath.extname( filePath ).slice(1);
	if( contentType[ext] ){
		type = contentType[ext];
	}else{
		type = contentType['stream'];
	}
	return type;
};
//}}}

//{{{fn show_status',
var statuses = {
	'100' : 'Continue',
	'101' : 'Switching Protocols',
	'200' : 'OK',
	'201' : 'Created',
	'202' : 'Accepted',
	'203' : 'Non-Authoritative Information',
	'204' : 'No Content',
	'205' : 'Reset Content',
	'206' : 'Partial Content',
	'300' : 'Multiple Choices',
	'301' : 'Moved Permanently',
	'302' : 'Found',
	'303' : 'See Other',
	'304' : 'Not Modified',
	'305' : 'Use Proxy',
	'307' : 'Temporary Redirect',
	'400' : 'Bad Request',
	'401' : 'Unauthorized',
	'403' : 'Forbidden',
	'404' : 'Not Found',
	'405' : 'Method Not Allowed',
	'406' : 'Not Acceptable',
	'407' : 'Proxy Authentication Required',
	'408' : 'Request Timeout',
	'409' : 'Conflict',
	'410' : 'Gone',
	'411' : 'Length Required',
	'412' : 'Precondition Failed',
	'413' : 'Request Entity Too Large',
	'414' : 'Request URI Too Long',
	'416' : 'Requested Range Not Satisfiable',
	'500' : 'Internal Server Error',
	'501' : 'Not Implemented',
	'502' : 'Bad Gateway',
	'503' : 'Service Unavailable',
	'504' : 'Gateway Timeout',
	'505' : 'HTTP Version Not Supported'
};
var show_status = function( res, status_nu ){
	res.writeHead( status_nu, {"Content-Type":"text/html"} );
	res.end( "<h1>" + status_nu + " " + statuses[status_nu] + "</h1>" );
};
//}}}

//{{{fn readFile
var readFile = function( res, filePath ){
	libFs.exists(filePath + index, function( exists ){
		//console.log( '++++++++' + filePath + index );
		if( !exists ){
			show_status( res, 404 );
		}else{
			res.writeHead( 200, {"Content-Type": getContentType(filePath),} );
			var stream = libFs.createReadStream( filePath, {flags : "r", encoding : null} );
			stream.pipe( res );
		}
	});
};
//}}}

//{{{fn dir_list
var dir_list = function( filePath, pathName, res ){
	libFs.readdir(filePath, function(err, files){
		res.writeHead(200, {'Content-Type': 'text/html'});
		var ret, name, i;
		if( pathName!=='/' ) pathName += '/';
		for(i in files){
			name = files[i];
			res.write( '<a href="http://' + hostPort + pathName + name + '">' + name + '</a><br />' );
			//console.log( name );
		}
		res.end( ret );
	});
};
//}}}

//fn do_get{{{
var do_get = function( req, res ){
	req.url = req.url.replace(/\/+/g, '/');
	//console.log( req.url );
	console.log( decodeURIComponent( req.url ) );
	var parsed_url = libUrl.parse( req.url, true, true);
	//console.log( parsed_url );
	var pathName = parsed_url.pathname;
	var filePath = decodeURIComponent( wwwRoot + pathName );
	//console.log( '--------' + filePath );
	try{
		route(res, filePath, pathName);
	}catch( e ){
		show_status( res, 500 );
	}
};
//}}}

//fn do_post{{{
var do_post = function(req, res){
	var post_data = '';
	req.setEncoding("utf8");

	req.addListener("data", function(chunk){
		post_data += chunk;
		console.log("Received POST data chunk '"+ chunk + "'.");
	});

	req.addListener("end", function() {
		post_data = libQs.parse( post_data );
		console.log( post_data );
		do_get(req, res);
	});
};
//}}}

//fn route{{{
var route = function( res, filePath, pathName ){
	libFs.exists(filePath, function( exists ){
		if( !exists ){
			show_status( res, 404 );
		}else{
			libFs.stat(filePath ,function(err, stats){
				if( stats.isDirectory() ){
					if( index ){
						readFile( res, filePath + index);
					}else{
						dir_list( filePath, pathName, res);
					}
				}else if( stats.isFile() ){
					readFile( res, filePath );
				}
			});
		}
	});
};
//}}}

//create service{{{
if (libCluster.isMaster) {
	for (var i = 0; i < libOs.cpus().length; i++) {
		libCluster.fork();
	}
	libCluster.on('exit', function(worker, code, signal) {
		console.log('worker ' + worker.process.pid + ' died');
	});
}else{
	var webSvr = libHttp.createServer(function( req, res ){
		req.setEncoding('utf8');
		if( req.method==='POST' ){
			do_post( req, res );
		}else if( req.method==='GET' ){
			do_get( req, res );
		}
	});
	webSvr.on("error", function( error ){
		console.log( error );
	});
	webSvr.listen(port, function(){
		//console.log( '[Service_start] running at http://localhost:' + port );
		//console.timeEnd( 'Service_start' );
	});
}
//}}}

/* vim: set fdm=marker tabstop=4 shiftwidth=4 softtabstop=4: */
